/**
 * 项目管理API服务类
 * 提供项目相关的所有API操作
 * 继承自BaseService，获得基础的CRUD操作方法
 * 并扩展了项目特有的业务方法
 */

// 导入依赖模块
// 导入基础服务类，获得通用的CRUD操作
import { BaseService } from '../base-service.js';
// 导入API端点配置，获取项目相关的接口路径
import { API_ENDPOINTS } from '../config.js';

// 项目服务类定义
// 继承自BaseService，获得基础的数据操作方法
class ProjectService extends BaseService {
  /**
   * 构造函数
   * 初始化项目服务的端点和配置
   * 使用API_ENDPOINTS.PROJECTS.LIST作为基础端点
   */
  constructor() {
    // 调用父类构造函数，设置API端点
    // replace操作确保端点路径正确（这里实际上没有变化，但保持了代码的一致性）
    super(API_ENDPOINTS.PROJECTS.LIST.replace('/projects', '/projects'));
  }

  /**
   * 获取项目列表
   * 获取符合条件的所有项目，支持分页、搜索、筛选等功能
   * @param {object} params - 查询参数对象
   * @param {number} params.page - 页码，从1开始，默认1
   * @param {number} params.pageSize - 每页数量，默认10，最大100
   * @param {string} params.search - 搜索关键词，会在项目名称、描述中搜索
   * @param {string} params.status - 项目状态筛选，可选值：active, completed, cancelled, archived
   * @param {string} params.type - 项目类型筛选，可选值：web, mobile, desktop, other
   * @param {string} params.managerId - 项目经理ID筛选，只显示指定经理负责的项目
   * @param {string} params.startDate - 开始日期筛选，格式：YYYY-MM-DD
   * @param {string} params.endDate - 结束日期筛选，格式：YYYY-MM-DD
   * @param {object} options - 请求选项配置
   * @returns {Promise<object>} 项目列表数据和分页信息
   */
  async getProjects(params = {}, options = {}) {
    // 调用父类的getList方法获取项目列表
    // 该方法会自动处理分页、搜索、排序等参数
    return this.getList(params, options);
  }

  /**
   * 获取项目详情
   * 根据项目ID获取单个项目的完整信息
   * @param {string|number} id - 项目的唯一标识符
   * @param {object} options - 请求选项配置
   * @returns {Promise<object>} 项目详细信息，包含基本信息和关联数据
   */
  async getProject(id, options = {}) {
    // 调用父类的getDetail方法获取项目详情
    return this.getDetail(id, options);
  }

  /**
   * 创建项目
   * 创建一个新的项目记录
   * @param {object} projectData - 项目数据对象
   * @param {string} projectData.project_name - 项目名称，必填字段
   * @param {string} projectData.project_type - 项目类型，可选值：web, mobile, desktop, other
   * @param {string} projectData.priority - 优先级，可选值：low, medium, high, urgent
   * @param {string} projectData.manager_id - 项目经理ID，必填字段
   * @param {string} projectData.start_date - 开始日期，格式：YYYY-MM-DD
   * @param {string} projectData.end_date - 结束日期，格式：YYYY-MM-DD，必须晚于开始日期
   * @param {number} projectData.budget - 项目预算，单位：元
   * @param {string} projectData.description - 项目描述
   * @param {string} projectData.objectives - 项目目标
   * @param {string} projectData.risk_level - 风险等级，可选值：low, medium, high
   * @param {Array<string>} projectData.team_members - 团队成员ID数组
   * @param {object} options - 请求选项配置
   * @returns {Promise<object>} 创建成功后的项目数据
   */
  async createProject(projectData, options = {}) {
    // 调用父类的create方法创建项目
    // 该方法会自动发送POST请求到项目创建端点
    return this.create(projectData, options);
  }

  /**
   * 更新项目
   * 完整更新项目的所有信息
   * @param {string|number} id - 项目的唯一标识符
   * @param {object} projectData - 要更新的项目数据对象
   * @param {object} options - 请求选项配置
   * @returns {Promise<object>} 更新成功后的项目数据
   */
  async updateProject(id, projectData, options = {}) {
    // 调用父类的update方法更新项目
    // 该方法会发送PUT请求，完整替换项目数据
    return this.update(id, projectData, options);
  }

  /**
   * 更新项目状态
   * 修改项目的当前状态，并记录变更原因和时间
   * @param {string|number} id - 项目的唯一标识符
   * @param {string} status - 新的项目状态，可选值：active, completed, cancelled, archived
   * @param {string} reason - 状态变更原因说明，可选参数
   * @param {object} options - 请求选项配置
   * @returns {Promise<object>} 更新成功后的项目数据
   */
  async updateProjectStatus(id, status, reason = '', options = {}) {
    // 调用父类的patch方法进行部分更新
    // 只更新状态相关的字段，不影响其他数据
    return this.patch(id, { 
      status,                                    // 新的项目状态
      status_change_reason: reason,             // 状态变更原因
      status_changed_at: new Date().toISOString() // 状态变更时间，ISO格式
    }, options);
  }

  /**
   * 更新项目进度
   * 修改项目的完成进度百分比
   * @param {string|number} id - 项目的唯一标识符
   * @param {number} progress - 进度百分比，范围0-100
   * @param {object} options - 请求选项配置
   * @returns {Promise<object>} 更新成功后的项目数据
   */
  async updateProjectProgress(id, progress, options = {}) {
    // 调用父类的patch方法进行部分更新
    // 确保进度值在有效范围内（0-100）
    return this.patch(id, { 
      progress_percentage: Math.max(0, Math.min(100, progress))
      // Math.max(0, ...) 确保进度不小于0
      // Math.min(100, ...) 确保进度不大于100
    }, options);
  }

  /**
   * 删除项目
   * @param {string|number} id - 项目ID
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 删除结果
   */
  async deleteProject(id, options = {}) {
    return this.delete(id, options);
  }

  /**
   * 批量删除项目
   * @param {Array<string|number>} ids - 项目ID数组
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 删除结果
   */
  async batchDeleteProjects(ids, options = {}) {
    return this.batchDelete(ids, options);
  }

  /**
   * 获取项目统计信息
   * @param {object} params - 统计参数
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 统计数据
   */
  async getProjectStats(params = {}, options = {}) {
    return this.getStats(params, options);
  }

  /**
   * 获取项目任务列表
   * @param {string|number} projectId - 项目ID
   * @param {object} params - 查询参数
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 任务列表
   */
  async getProjectTasks(projectId, params = {}, options = {}) {
    return this.getList({
      ...params,
      project_id: projectId,
    }, options);
  }

  /**
   * 获取项目团队成员
   * @param {string|number} projectId - 项目ID
   * @param {object} options - 请求选项
   * @returns {Promise<Array>} 团队成员列表
   */
  async getProjectMembers(projectId, options = {}) {
    return this.getDetail(`${projectId}/members`, options);
  }

  /**
   * 添加项目成员
   * @param {string|number} projectId - 项目ID
   * @param {object} memberData - 成员数据
   * @param {string} memberData.user_id - 用户ID
   * @param {string} memberData.role - 角色
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 添加结果
   */
  async addProjectMember(projectId, memberData, options = {}) {
    return this.create(`${projectId}/members`, memberData, options);
  }

  /**
   * 移除项目成员
   * @param {string|number} projectId - 项目ID
   * @param {string|number} memberId - 成员ID
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 移除结果
   */
  async removeProjectMember(projectId, memberId, options = {}) {
    return this.delete(`${projectId}/members/${memberId}`, options);
  }

  /**
   * 获取项目文件
   * @param {string|number} projectId - 项目ID
   * @param {object} options - 请求选项
   * @returns {Promise<Array>} 文件列表
   */
  async getProjectFiles(projectId, options = {}) {
    return this.getFiles(projectId, options);
  }

  /**
   * 上传项目文件
   * @param {string|number} projectId - 项目ID
   * @param {File|FileList} files - 文件
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 上传结果
   */
  async uploadProjectFiles(projectId, files, options = {}) {
    return this.uploadFiles(projectId, files, options);
  }

  /**
   * 获取项目进度报告
   * @param {string|number} projectId - 项目ID
   * @param {object} params - 查询参数
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 进度报告
   */
  async getProjectProgressReport(projectId, params = {}, options = {}) {
    return this.getDetail(`${projectId}/progress-report`, {
      query: params,
      ...options,
    });
  }

  /**
   * 获取项目甘特图数据
   * @param {string|number} projectId - 项目ID
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 甘特图数据
   */
  async getProjectGanttData(projectId, options = {}) {
    return this.getDetail(`${projectId}/gantt`, options);
  }

  /**
   * 复制项目
   * @param {string|number} projectId - 项目ID
   * @param {object} copyData - 复制配置
   * @param {string} copyData.name - 新项目名称
   * @param {boolean} copyData.copy_tasks - 是否复制任务
   * @param {boolean} copyData.copy_members - 是否复制成员
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 复制结果
   */
  async copyProject(projectId, copyData, options = {}) {
    return this.create(`${projectId}/copy`, copyData, options);
  }

  /**
   * 归档项目
   * @param {string|number} projectId - 项目ID
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 归档结果
   */
  async archiveProject(projectId, options = {}) {
    return this.patch(projectId, { 
      status: 'archived',
      archived_at: new Date().toISOString()
    }, options);
  }

  /**
   * 恢复项目
   * @param {string|number} projectId - 项目ID
   * @param {object} options - 请求选项
   * @returns {Promise<object>} 恢复结果
   */
  async restoreProject(projectId, options = {}) {
    return this.patch(projectId, { 
      status: 'active',
      restored_at: new Date().toISOString()
    }, options);
  }
}

// 创建单例实例
export const projectService = new ProjectService();

export default ProjectService;
